package org.example.ruoxing_admin_springboot3.Interceptor;
import com.fasterxml.jackson.databind.ObjectMapper;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.example.ruoxing_admin_springboot3.dao.UserInfoDao;
import org.example.ruoxing_admin_springboot3.httpResponseResult.ResponseResult;
import org.example.ruoxing_admin_springboot3.mapper.UserInfoMapper;
import org.example.ruoxing_admin_springboot3.utils.JWTUtils;
import org.example.ruoxing_admin_springboot3.utils.StringValidatorUtils;
import org.example.ruoxing_admin_springboot3.utils.TimestampUtil;
import org.springframework.lang.NonNull;
import org.springframework.lang.Nullable;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import java.util.List;
/**
 * @description 接口的拦截器，用于验证用户的身份，并获取用户信息
 * @author 莫若省
 * @createTime 2024/5/14
*/
public class WebApiInterceptor implements HandlerInterceptor {
    @Resource
    private UserInfoMapper userInfoMapper;
    /**
     * @description 白名单接口，不需要登录验证
     * @createTime 2024/5/14
    */
    private static final List<String> WHITE_API_LIST = List.of(
            "/v3/swagger",
            "/v3/api-docs",
            "/swagger-ui/",
            "/swagger-ui.html",
            "/swagger-ui/*",
            "/login",
            "/verificationCode/create",
            "/logout",
            "/login_sso",
            "/test"
    );
    /**
     * @description 异常情况的响应对象容器
     * @createTime 2024/5/14
     */
    private final ObjectMapper objectMapper = new ObjectMapper();

    @Override
    public boolean preHandle(HttpServletRequest request, @NonNull HttpServletResponse response, @NonNull Object handler) throws Exception {
        request.setAttribute("startTime", TimestampUtil.getCurrentMillisTimestamp());
        request.setAttribute("userName", "未知用户");
        String requestURI = request.getRequestURI();
        if (isWhiteListed(requestURI)) {
            return true;
        }
        response.setContentType("application/json;charset=UTF-8");
        String token = request.getHeader("x-access-token");
        //空token的处理
        if (StringValidatorUtils.isEmpty(token)) {
            response.getWriter().write(objectMapper.writeValueAsString(ResponseResult.ERROR("未检测到有效凭证!")));
            return false;
        }
        //非法token的处理
        if (!JWTUtils.validateToken(token)) {
            response.getWriter().write(objectMapper.writeValueAsString(ResponseResult.ERROR("解析失败,非法凭证!")));
            return false;
        }
        UserInfoDao userInfo = userInfoMapper.getUserInfoByToken(token);
        if (userInfo == null) {
            response.getWriter().write(objectMapper.writeValueAsString(ResponseResult.ERROR("非法用户!")));
            return false;
        }
        request.setAttribute("userName", userInfo.getUserName());
        //token过期的处理
        if (JWTUtils.isTokenExpired(token)) {
            userInfo.setUserCurrentToken(null);
            userInfoMapper.updateUserTokenByUserId(userInfo);
            response.getWriter().write(objectMapper.writeValueAsString(ResponseResult.WARN_AUTH()));
            return false;
        }
        return true;
    }

    private boolean isWhiteListed(String requestURI) {
        return WHITE_API_LIST.stream().anyMatch(requestURI::startsWith);
    }
    @Override
    public void postHandle(@NonNull HttpServletRequest request, @NonNull HttpServletResponse response, @NonNull Object handler, @Nullable ModelAndView modelAndView) throws Exception {
        Long responseTime = TimestampUtil.getCurrentMillisTimestamp() - (Long) request.getAttribute("startTime");
        // Optionally log the response time
    }

    @Override
    public void afterCompletion(@NonNull HttpServletRequest request, @NonNull HttpServletResponse response, @NonNull Object handler, @Nullable Exception ex) throws Exception {
        // Clean up resources if necessary
    }
}
